package navigation;

/**
 * Represents a field of the map
 *
 * @author hyurah
 */

public class Field {

	private FieldDirectionState[] directions;
	private boolean known;
	private boolean deadEnd;

	/**
	 * Constructs an unknown Field
	 */

	public Field() {
		known = false;
		deadEnd = false;
		directions = new FieldDirectionState[4];
		for(int i=0; i<directions.length; i++) {
			directions[i]=FieldDirectionState.UNKNOWN;
		}
	}

	/**
	 * Checks if this field is known
	 *
	 * @return true if field is known
	 */

	public boolean isKnown() {
		return known;
	}

	/**
	 * Checks if this field is a deadend
	 *
	 * @return true if field is a deadend
	 */

	public boolean isDeadEnd() {
		return deadEnd;
	}

	/**
	 * Checks if this field is a deadend thats reachable from the specified direction
	 *
	 * @param direction direction of the entrance
	 * @return true if field is deadend and has its entrance at the specified direction
	 */

	public boolean isDeadEnd(int direction) {
		return deadEnd && directions[direction]==FieldDirectionState.PATH;
	}

	/**
	 * Set field state
	 *
	 * @param north field has a path to the north
	 * @param east field has a path to the east
	 * @param south field has a path to the south
	 * @param west field has a path to the west
	 */

	public void setField(boolean north, boolean east, boolean south, boolean west) {
		known = true;
		if(north) setPathFound(Direction.NORTH);
		else setEmptyFound(Direction.NORTH);
		if(east) setPathFound(Direction.EAST);
		else setEmptyFound(Direction.EAST);
		if(south) setPathFound(Direction.SOUTH);
		else setEmptyFound(Direction.SOUTH);
		if(west) setPathFound(Direction.WEST);
		else setEmptyFound(Direction.WEST);
	}

	/**
	 * Set specified direction to have a path if it was previously unknown
	 *
	 * @param direction direction of the path
	 */
	
	public void setPathFound(int direction) {
		if(directions[direction]==FieldDirectionState.UNKNOWN)
			directions[direction]=FieldDirectionState.PATH;
	}

	/**
	 * Set specified direction to have no path if it was previously unknown
	 *
	 * @param direction direction of the missing path
	 */

	public void setEmptyFound(int direction) {
		if(directions[direction]==FieldDirectionState.UNKNOWN)
			directions[direction]=FieldDirectionState.EMPTY;
	}

	/**
	 * Forces specified direction to have no path
	 *
	 * @param direction direction of the missing path
	 */

	public void forceEmptyFound(int direction) {
		directions[direction]=FieldDirectionState.EMPTY;
	}

	/**
	 * Set this field to contain an object
	 */

	public void setObjectFound() {
		known = true;
		deadEnd = true;
		forceEmptyFound(Direction.NORTH);
		forceEmptyFound(Direction.EAST);
		forceEmptyFound(Direction.SOUTH);
		forceEmptyFound(Direction.WEST);
	}

	/**
	 * Set this field to be a deadend
	 *
	 * @param direction direction of the entrance of this deadend
	 */

	public void setDeadEndFound(int direction) {
		known = true;
		deadEnd = true;
		for(int i=0; i<directions.length; i++) {
			directions[i]=FieldDirectionState.EMPTY;
		}
		directions[direction]=FieldDirectionState.PATH;
	}

	/**
	 * Get state of specified field direction
	 *
	 * @param direction direction of requested state
	 * @return state of specified field direction
	 */

	public FieldDirectionState getFieldDirectionState(int direction) {
		return directions[direction];
	}

}
